1. /* sdbl.h by K.Tsuru */
  2. // file ID = 30 DRADIX
  3. #ifndef S_DOUBLE_H
  4. #define S_DOUBLE_H
  5. /***************************************************************************
  6. SDouble class
  7. Multi precision real number class in radix DRADIX = 10000
  8. The inner expression.
  9. <<floating point mode(standard form)>>
  10. [+|-]f[0].f[1]...f[ef]...f[s-1]*DRADIX^rdxExp (f[0]=0, f[1]>0)
  11. ef is effective figures. Last h figures are assigned to the hidden precision.
  12. Exponent "rdxExp" has value between INT_MIN (-2147483647 - 1) and INT_MAX 2147483647 on GCC.
  13. <<fixed point mode>>
  14. [+|-]f[0].f[1]...f[ef]...f[s-1]*DRADIX^fixedExp (f[0]=f[1]=...=f[aHead-1]=0)
  15. ****************************************************************************/
  16. SDouble SFToSD(const SFraction& x);//SFraction-->SDouble 300
  17. /*------------------------------------------------------------
  18. Radix conversion double x to array res[] in BRADIX.
  19. ------------------------------------------------------------*/
  20. int doubleToBinDec(double x, FigBlock& res, uint *size);
  21. class SDouble : public SNumber, public virtual SCalcInfo {
  22. friend class SDecimal; // To enable Reform accessible.
  23. friend class SLong; // 'figure' accessible in SL::SetSDouble()
  24. // Fixed value of exponent in the fixed point mode.
  25. static int fixedExp;
  26. // If lower seven bits of fixedPointMode is non-zero, it is fiexed point mode.
  27. // fixedPointMode = depth of nest
  28. static int fixedPointMode;
  29. // automatic radix conversion BIN_DEC to REAL cannot use.
  30. SDouble& operator=(const SDecimal& sd); // has no body
  31. enum { FIXED_PT_MASK = 0x7f };
  32. int rdxExp; // exponential value in radix = DRADIX
  33. protected:
  34. void CopyDouble(const SDouble& r, int cs); // 301
  35. // Functions which set several kinds of value
  36. // By string in type "[+|-]ddd.ddd...[e[+|-]dd]"
  37. void SetString(const char* s); // 302
  38. // Substitution double includes integer type variables, long etc.
  39. // If type == BIN_DEC and cyclic decimal, syntax error will occur.
  40. void SetDouble(double d); // 303
  41. public:
  42. void SetLongDouble(long double d);
  43. protected:
  44. void SetSLong(const SLong& sl); // 304 SLong
  45. // Return an ASCI code of (n+1)-th digit. Uses in function Put().
  46. int CharNthDec(long n) const; // 306
  47. // Make a zero with type = tp.
  48. // Uses in return statement in SDouble.
  49. friend SDouble SDZero(const SDouble& d); // 307
  50. // Dec 25, 2000 Move into protected part.
  51. // Temporary maximum size changed by SetEffFig() function.
  52. // Need for the functions using Newton method.
  53. uint CurrentMaxSize() const {
  54. return SNEffFig( Type() ) + Hidden() + 1u;
  55. }
  56. public:
  57. // May 16, 2001 Move into public part from protected one.
  58. // Make a SLong value r = (f[h],...f[t]).
  59. void ConvertToSLong(uint t, uint h, SLong& r) const; // 305
  60. /************************************************************************
  61. Additional values for pushCD.
  62. SD_PUSH bit is one, when a SDouble object change the value cutDownTable[].
  63. pushCD = 0...4 are registered in SNumber class, then greater than 4.
  64. **************************************************************************/
  65. enum { CH_FE = 8, SD_PUSH = 16, TEMP_FREE = 32, REDUCE_MAX_SIZE_DISABLE = 64 };
  66. // set zero(sign = ZERO, all the elements of figure[] are seted by zero)
  67. void SetZero(); // inline function
  68. /*******************
  69. Set a short value.
  70. ********************/
  71. void SetInt(int v); // 308
  72. // rdexp is exponential value in SDouble class
  73. // In SDecimal class rdxExp always set zero for any value of rdxexp.
  74. void SetSmall(signed char v, int rdexp = 1);
  75. // Effective figures. In BRADIX return a value diffrent from SNManager::EffFigures().
  76. uint EffFig() const { return SNEffFig( Type() ); }
  77. uint Size() const {
  78. return min(SNEffFig( Type() ) + Hidden() + 1u, figure.size());
  79. }
  80. uint MinSize() const {
  81. return (Type() == REAL) ? minArraySize : SNMaxSize(BIN_DEC);
  82. }
  83. /**********************************************************************
  84. return the exponetial part
  85. [Notice] raw value in fiexed point mode.
  86. The value in the "standard" form i.e. [+|-]f[0].f[1]... * R^e (f[1] >0)
  87. can be obtained by NetRdxExp().
  88. ***********************************************************************/
  89. int RdxExp() const { return rdxExp; }
  90. int NetRdxExp() const {
  91. return Sign(30) ? rdxExp - (int)aTail +1 : 0;
  92. }
  93. /******************************************
  94. Set an exponential value in radix = DRADIX
  95. When e = 0, you get the mantissa part.
  96. *******************************************/
  97. void SetRdxExp(long e) {
  98. if( (Type() == BIN_DEC) && e ) SetError(SYNTAX_ERR,"SD", 31);
  99. if(labs(e) > DRADIX_EXP_MAX ) SetError(TOO_LARGE_EXP,"SD", 31);
  100. rdxExp = (int)e;
  101. }
  102. /*********************************************************
  103. Return the sign
  104. In the fixed point mode if non-zero elements are out of
  105. maxmum size(CurrentmaxSize()), return zero.
  106. **********************************************************/
  107. int Sign(int id) const; // inline function.
  108. int Sign() const { return Sign(32); }
  109. /******************************************************
  110. Return raw sign of SNumber class.
  111. If sign == UNDECIDED, the program abnormally terminate.
  112. *******************************************************/
  113. int SNSign() const { SignCheck(33); return (int)RawSign(); }
  114. /***************************************************************
  115. Return the decimal exponent in standard form.
  116. t
  117. 0.|0000|0000|0aaa|bbbb|...|zzzz| * DRADIX^e
  118. --> 0.0aaabbbb...zzzz * 10000^(e-t+1)
  119. --> 0.aaabbbb...zzzz * 10^p p = 4*(e-t+1) -4 +3
  120. ****************************************************************/
  121. long DExp() const {
  122. if(Sign(34) == 0) return 0;
  123. return (long)DFIGURES*(NetRdxExp() - 1L) + iFigures(figure(aTail));
  124. }
  125. //Return decimal figures
  126. long DFigures() const; // 309
  127. //Composed by hidden figures only or not.It is available in fixed point mode only.
  128. bool IsHidden() const; // inline function defined bellow
  129. //*this is much less than "a" ?
  130. bool IsMLT(const SDouble& a) const; // 310
  131. //Return the position of first non-zero element.
  132. //In the standard form aTail = 1 or 0(if sign==0).
  133. //In fixed point mode it is maybe greater than one.
  134. uint First() const { return aTail < CurrentMaxSize() ? aTail : 0; }
  135. private:
  136. uint GetLastPosition() const; // 311
  137. public:
  138. //Return the position of last non-zero element.
  139. //Last() < CurrentMaxSize()
  140. uint Last() const {
  141. if(aHead < CurrentMaxSize()) return aHead;
  142. return GetLastPosition(); //0.abcd 0000 ..... 0000 1234, return 1
  143. }
  144. // Head() and Tail() return raw value of SNumber class.
  145. // Please use First()/Last() if possible. ver. 2.17
  146. uint Head() const { return aHead; }
  147. uint Tail() const { return aTail; }
  148. public:
  149. /**************** For making mathematical functions ************************/
  150. /*----------------------------------------------------------------------
  151. Take into the fixed point mode setting the fixed exponent value by "fe".
  152. Use in the calculation of series summantion.
  153. In principle do not call mathmatical functions in the fixed point mode.
  154. The general term of the floating and fixed point modes is named as the
  155. "operation mode".
  156. -----------------------------------------------------------------------*/
  157. void FixedPoint(int fe); // 312 DRADIX
  158. /*--------------------
  159. Cancel fixed point mode.
  160. ---------------------*/
  161. //Use with FixedPoint().
  162. void PointFree(); // 313 DARDIX
  163. //fixed exponent value
  164. int FixedExp() const { return (Type() == BIN_DEC) ? 0 : fixedExp; }
  165. //It is in the fixed point mode or not. Return the depth of nest.
  166. int IsPointFixed() const {
  167. return (Type() == BIN_DEC) ? 1 : (fixedPointMode & FIXED_PT_MASK);
  168. }
  169. //Take into the fixed point mode for a moment. See Log(x) for usage.
  170. void TempPointFree(){
  171. PushCD(PushedCD() | TEMP_FREE);
  172. fixedPointMode *= (FIXED_PT_MASK+1);
  173. }
  174. //Restore the operation mode in one step. Use with TempPointFree().
  175. void PointModePop() {
  176. if(!(PushedCD() & TEMP_FREE) ) SetError(SYNTAX_ERR,"PointModePop", 31);
  177. PushCD(PushedCD() & ~TEMP_FREE);
  178. fixedPointMode = fixedPointMode/(FIXED_PT_MASK+1) + (fixedPointMode & FIXED_PT_MASK);
  179. }
  180. /*---------------------------------------------------------------------------
  181. Reform into a representation which is sutable for the present operation mode.
  182. Adjust the size of figure[] i.e. if cutDown != DISABLE it cuts lower needless
  183. zeros.
  184. If the top figure(figure[0]) becomes non-zero by a carry, it shifts to lower
  185. by a figure and makes aTail=1.
  186. Excute after directly changing the elements of figure[] or restoring the
  187. operation mode.
  188. Give to "id" an error ID number of the place in the program.
  189. ------------------------------------------------------------------*/
  190. void Reform(int id); // 314
  191. //Even if in the fixed point mode it changes into a standard form. DRADIX only
  192. void StdReform(int id); // 315
  193. //Set a long real number by "FigBlock",sign and rdxExp.
  194. void SetFigBlock(const FigBlock& a, int sgn, int exp){
  195. SNumber::SetFigBlock(a, sgn);
  196. SetRdxExp(exp);
  197. Reform(35);
  198. }
  199. //Normalize() version
  200. void SetFigBlockNorm(const FigBlock& a, int sgn, int exp){
  201. SNumber::SetFigBlockNorm(a, sgn);
  202. SetRdxExp(exp);
  203. Reform(36);
  204. }
  205. //If size is greater than "minArraySize" it takes into fixed point mode.
  206. void FigureAlloc(uint size, int copy){
  207. SNumber::FigureAlloc(size, copy);
  208. if(copy <= 0) rdxExp = 0;
  209. }
  210. /*-----------------------------------------------------------------------------
  211. Try to convert SDouble "d" using long "L" into a form
  212. d = L * 10^e ( 0 =< |L| <= ULONG_MAX/DRADIX).
  213. When it is successed, return one. The operation can be reduced into one between
  214. SDouble and short integer.
  215. e.g. d=1.5, x/d ---> (x/15000)*DRADIX.
  216. The multiplication with DRADIX can be done by MultPowRdx(1).
  217. -------------------------------------------------------------------------------*/
  218. bool ConvTolongExp(long* L, long* e) const; // 316
  219. /********************************************************************************/
  220. //constructors
  221. SDouble():SNumber(REAL), rdxExp(0){}
  222. SDouble(double d):SNumber(REAL), rdxExp(0){
  223. SetDouble(d);
  224. }
  225. // SDouble(long double ld):SNumber(REAL), rdxExp(0){ SetLongDouble(ld); }
  226. SDouble(const char* s):SNumber(REAL), rdxExp(0){
  227. SetString(s);
  228. }
  229. //This is necessary to convert SD*SL into SD*SD.
  230. SDouble(const SLong& sl):SNumber(REAL){ SetSLong(sl); }
  231. /***************************************************************************
  232. tp=REAL or BIN_DEC
  233. vsz=size of figure[], See FigureAlloc()
  234. If vsz > 0, it is initialized by zero.
  235. If vsz > minArraySize, it takes into fixed point mode and executes
  236. CutDown(DISABLE).
  237. ****************************************************************************/
  238. SDouble(NumberType tp, uint vsz); //33
  239. // copy constructor
  240. SDouble(const SDouble& a):SNumber(a), rdxExp(a.rdxExp){}
  241. /*************************************************
  242. Constructor for SFraction --> SDouble.
  243. It will be natural to convert SD*SF into SD*SD.
  244. **************************************************/
  245. SDouble(const SFraction& sf); // 34
  246. #if 0
  247. //no use and has no body
  248. SDouble(const SDecimal& sd);
  249. #endif
  250. //destructor : PointFree()
  251. ~SDouble(); // 35
  252. //"SLong = SDouble" has been defined in SLong class.
  253. SDouble& operator=(const char *s) { SetString(s); return *this; }
  254. SDouble& operator=(double d){ SetDouble(d); return *this; }
  255. // SDouble& operator=(ldouble ld){ SetLongDouble(ld); return *this; } // double version
  256. SDouble& operator=(const SLong& sl){
  257. SetSLong(sl); return *this;
  258. }
  259. SDouble& operator=(const SDouble& sd){
  260. if(this != &sd) CopyDouble(sd, SUBS);
  261. return *this;
  262. }
  263. //Convert SFracrion into SDouble.
  264. SDouble& operator=(const SFraction& sf); // 36
  265. //Compare absolute values.
  266. friend int DDCompare(const SDouble& m, const SDouble& n); // 320
  267. //Auxiliary functions for four operations.
  268. //It cannot use as DsDiv(1.0, 3); for 1/3 = 0.33333... Use a cast as z = DsDiv(SDouble(1.0), 3); since version 2.20
  269. friend SDouble DDAdd(const SDouble& m, const SDouble& n); // 321
  270. friend SDouble DDSub(const SDouble& m, const SDouble& n); // 322
  271. friend SDouble DsMult(const SDouble& m, ulong n); // 323
  272. friend SDouble DDMult(const SDouble& m, const SDouble& n);// 324
  273. friend SDouble DsDiv(const SDouble& m, ulong n); // 325
  274. //Get the reciprocal of "x" by the Newton's method. It is used in y/x.
  275. friend SDouble DReciprocal(const SDouble& x); // 326
  276. friend SDouble DDiv2(const SDouble& n); //diveide "n" by two 327
  277. //four operators
  278. friend SDouble operator+(const SDouble& m, const SDouble& n);//330
  279. friend SDouble operator-(const SDouble& m, const SDouble& n);// 331
  280. friend SDouble operator*(const SDouble& m, const SDouble& n);//324
  281. //Does not provide other operators "SD*int", "SD*long", etc.
  282. friend SDouble operator*(const SDouble& m, double d); // 332
  283. friend SDouble operator*(double d, const SDouble& m){ return m*d; }
  284. friend SDouble operator/(const SDouble& m, const SDouble& n);// 333
  285. friend SDouble operator/(const SDouble& m, double d); // 334
  286. /*
  287. For two operators "+=" and "-=" when 'n' is equal to zero,
  288. it may be better that it returns "*this" only.
  289. But it is rare case and the copy will cost little time.
  290. */
  291. SDouble& operator+=(const SDouble& n) { return (*this = *this + n); }
  292. SDouble& operator-=(const SDouble& n) { return (*this = *this - n); }
  293. SDouble& operator*=(const SDouble& n) { return (*this = *this * n); }
  294. SDouble& operator*=(double d) { return (*this = *this * d); }
  295. SDouble& operator/=(const SDouble& n) { return (*this = *this / n); }
  296. SDouble& operator/=(double d) { return (*this = *this / d); }
  297. /**********************************************************************
  298. [Caution]
  299. Please use cast the operations between diffrent type variavles.
  300. SD=0.1*SL yields SD=0.0. --> SD=0.1*(SDouble)SL;
  301. When SL=10, SD=0.1+SL yields SD=10.0 not 10.1. --> SD=0.1+(SDouble)SL;
  302. These are expectative if lhs is SL.
  303. ***********************************************************************/
  304. //sign opertors
  305. SDouble operator+() const { return *this; }
  306. SDouble operator-() const; // 335
  307. //multiplied by radix^n
  308. SDouble& MultPowRdx(int n); // 340
  309. //multiplied by 10^p, DRADIX only
  310. SDouble& MultPow10(long p); // 341
  311. //round off to the last decimal place of effective figures
  312. enum { STD_REF = 1, CUR_MAX = 2 };
  313. SDouble& Round(int std = STD_REF); // 342
  314. /**********************************************************************
  315. Is possible to round off or not.
  316. If the number of continuous (radix-1) or zero from the last decimal place
  317. of effective figures is greater than or equal "n" return 1, else 0.
  318. Use to round off
  319. 0.1233 9999 9999 9999 ..... 9999 9875 4578
  320. or
  321. 0.1234 0000 0000 0000 ..... 0000 0000 0001
  322. into 0.1234.
  323. Does not include Reform(), then call it if necessary.
  324. [usage]
  325. if(r.IsPossibleToRound(3)) r.Round(0);
  326. ************************************************************************/
  327. public:
  328. bool IsPossibleToRound(uint n) const; // 343
  329. /****************************************************************************
  330. output functions
  331. 0.abcde fghij kl ......... wxyz : perLine
  332. <-fU=5->..................
  333. Put() : not carridge return, Puts() : feed new line
  334. 1) If fig(Unit) == 0, it continuously outputs with neither delimiter nor carridge return.
  335. 2) putFig : the number of decimal figures. default : putFig = 0 all figures
  336. 3) perLine = the number of blocks which contains "fig" decimal per line
  337. default : perLine = 0 automatically set perLine = displayWidth/(fig+1)
  338. 4) lineFormat : NO_CR, CRLF, CONTINUE and END_CR have same meaning as SLong class's ones.
  339. ROUND : do Round() or not.
  340. INT_PUT : It outputs a decimal figure as integer part.
  341. SHOW_FIG: It shows the number of decimal figures at end of line and adds carridge return.
  342. 5) Insert delimiter given by "delmt" at intervals of "fig(Unit)" characters.
  343. If delmt == 0, no delimiter is inserted.
  344. It returns the total number of output bytes, including '\n', '.' and delimiter,
  345. as "printf()".
  346. --------------------------------------------------------------------------------------------
  347. void SetFormat(long f, long pf = 0, int pL = 0, int lF = CRLF|ROUND|INT_PUT, int dm = ' ');
  348. ******************************************************************************/
  349. static long figUnit;
  350. static long putFig;
  351. static int perLine;
  352. static int lineFormat;
  353. static int delmt;
  354. static long ioCount; // the number of input or output characters
  355. static long crCount; // added version 2.30
  356. enum { NO_CR = 0, CRLF = 1, CONTINUE = 2, END_CR =4 , ROUND = 8,
  357. INT_PUT = 16, SHOW_FIG = 32 };
  358. static void SetFormat(long fU, long pF = 0, int pL = 0, int lF = ROUND|INT_PUT|CRLF, int dm = ' '); // 359
  359. static void DefaultFormat(); // It restores the default values. 360
  360. // They return the number of output charakuters. Please use these to know it in stead of "cout << sd;".
  361. long Put(long fU=10, long pf = 0, int pL=0, int lF = CRLF|ROUND|INT_PUT, int dm=' ') const; // 344
  362. // If fU<0 parameters by SetFormat() are used example Put(-1);
  363. long Puts(long fU=10, long pr = 0, int pL=0, int lF = CRLF|ROUND|INT_PUT, int dm=' ') const; // x.Puts()
  364. //It outputs the inner expression.
  365. long RawPut(int crlf = 0) const; // 355
  366. long RawPuts() const { return RawPut(1); }
  367. long CRCount(bool reset=true) const { long temp = crCount; if(reset) crCount = 0; return temp; }
  368. friend ostream& operator<<(ostream& os, const SDouble& sd); // added since version 2.21 // 356
  369. //It makes an approximated value taking first "fig" figures.
  370. SDouble TakeOutFigures(uint fig) const; // 356
  371. // |*this| == 1 ?
  372. int IsOne() const {
  373. if(aHead != aTail) return 0;
  374. if(NetRdxExp() != 1) return 0;
  375. return figure(aHead) == 1u ? Sign() : 0;
  376. }
  377. /*******************************************************************************
  378. It examines whether it is proper to grade up the degree of precision by "upPrec"
  379. figures.When the size of figure[] exceed the power of two only a few, the
  380. efficiency of memory is bad and the merit of FFT multiplication is killed.
  381. It is used in Exp(x), etc.
  382. 1.When preferSpeed is ON
  383. If MaxSize()+upPrec >=2^n, return 0 else 2^n - MaxSize().
  384. In this case the precision will be lost by few percents.
  385. 2.When preferSpeed is OFF(addvance precison,default)return "upPrec".
  386. *******************************************************************/
  387. uint ProperUpPrec(uint upPrec) const; // 357
  388. };
  389. /**************** end of SDouble class ******************/
  390. //It moves "fixedPointMode" value to upper bits.
  391. inline int SDouble::Sign(int id) const {
  392. int snsign = SNumber::Sign(id);
  393. if(!snsign || !IsPointFixed() || (Type() == BIN_DEC)) return snsign;
  394. int e = (int)aTail - rdxExp + fixedExp;
  395. return (e < (int)CurrentMaxSize()) ? snsign : 0;
  396. }
  397. inline void SDouble::SetZero(){
  398. rdxExp = 0; SNumber::SetZero();
  399. }
  400. inline long SDouble::Puts(long fig, long pr, int perLine, int lF, int delmt) const {
  401. long l = Put(fig, pr, perLine, lF, delmt);
  402. FPutc('\n');
  403. return l+1;
  404. }
  405. inline bool SDouble::IsHidden() const {
  406. if(SNumber::Sign(37) == 0) return true;
  407. return aTail > EffFig() ? true : false;
  408. }
  409. // SDouble contants added since version 2.30
  410. static const SDouble ONE(1.0); // one
  411. static const SDouble ZERO(0.0); // zero
  412. /* defined in template in "mathtp.h"
  413. inline istream& operator>>(istream& s, SDouble& a) // added since version 2.21
  414. {
  415. string buf;
  416. std::getline(s, buf); // usage : cin >> a; ( s = cin )
  417. a = buf.data();
  418. return s;
  419. }
  420. */
  421. #endif // S_DOUBLE_H

sdbl.h : last modifiled at 2017/10/18 15:19:28(19,674 bytes)
created at 2016/04/11 11:18:58
The creation time of this html file is 2017/10/23 10:29:22 (Mon Oct 23 10:29:22 2017).